package cn.gogetter.clusterer;

import java.io.File;
import java.io.FileWriter;

import weka.clusterers.ClusterEvaluation;
import weka.clusterers.EM;
import weka.core.Instances;
import weka.core.Utils;
import weka.core.converters.ConverterUtils.DataSource;

/**
 * 本例展示在训练集上构建EM聚类器，然后在测试集上预测簇并输出簇的隶属度
 */
public class OutputClusterDistribution {
	private static FileWriter fw;

	public static void main(String[] args) throws Exception {
		// 加载数据
		
		String filename = new File("").getAbsolutePath()+"\\data\\"+ "segment-challenge.arff";
		Instances train = DataSource.read(filename);
		String testname = new File("").getAbsolutePath()+"\\data\\"+ "segment-test.arff";
		Instances test = DataSource.read(testname);
		if(!train.equalHeaders(test)){
			throw new Exception("训练集和测试集不兼容："+train.equalHeadersMsg(test));
		}
		File file = new File("outfile.txt");
		if(!file.exists()){
			file.createNewFile();
		}
		fw = new FileWriter(file,true);
		
		// 构建聚类器
		EM clusterer = new EM();
		clusterer.buildClusterer(train);
		System.out.println("//构建聚类器\r\n");
		fw.write("//构建聚类器\r\n");
		System.out.println(clusterer);
		fw.write(clusterer+"\r\n");
		// 评估聚类器
		ClusterEvaluation eval = new ClusterEvaluation();
		eval.setClusterer(clusterer);
		eval.evaluateClusterer(test);
		System.out.println("// 输出评估结果");
		fw.write("//输出评估结果\r\n");
		System.out.println(eval.clusterResultsToString());
		fw.write("\r\n"+eval.clusterResultsToString()+"\r\n");
		// 输出预测
		System.out.println("编号 - 簇 \t-\t 分布");
		fw.write("编号\t -\t 簇\t -\t 分布\r\n");
		for(int i = 0; i < test.numInstances(); i++){
			int cluster = clusterer.clusterInstance(test.instance(i));
			double[] dist = clusterer.distributionForInstance(test.instance(i));
			fw.write((i+1)+"\t -\t "+cluster+"\t -\t "+Utils.arrayToString(dist)+"\r\n");
			System.out.print((i+1));
			System.out.print(" - "); 
			System.out.print(cluster);
			System.out.print(" - "); 
			System.out.print(Utils.arrayToString(dist));
			System.out.print("\r\n"); 
			fw.flush();
		}
		System.out.println(file.getAbsolutePath());
			
	}
}
